<?php

include "ObjectFactory.class.php";

use pmvc\ioc\ObjectFactory;
use pmvc\ioc\ObjectDescriptor;
use pmvc\ioc\PropertyDescriptor;
use pmvc\ioc\InitializingObject;

class ObjectA {
	public $prop1 = 100;
	private $anotherObject = NULL;
	public function setAnotherObject($val) {
		$this->anotherObject = $val;
	}
}

class ObjectB {
	public $prop1 = 100;
	public $prop2 = 100;
	public function ObjectB($prop1, $prop2=10) {
		$this->prop1 = $prop1;
		$this->prop2 = $prop2;
	}
}

class ObjectC {
	public $balls;
}

class ObjectD
	implements InitializingObject {
	public $initialized = FALSE;
	function initialize($objectFactory) {
		$this->initialized = true;
	}
}

$factory = new ObjectFactory();

$factory->addObjectDescriptor(
	new ObjectDescriptor("object1", "ObjectA")
);
$factory->addObjectDescriptor(
	new ObjectDescriptor("object2", "ObjectA", Array(
		new PropertyDescriptor("prop1", "object2, prop1")
	))
);
$factory->addObjectDescriptor(
	new ObjectDescriptor("object3", "ObjectA", Array(
		new PropertyDescriptor("prop1", "object2, prop1"),
		new PropertyDescriptor("anotherObject", NULL, "object1"),
		new PropertyDescriptor("anotherObject", NULL, "object1")
	))
);
$factory->addObjectDescriptor(
	new ObjectDescriptor("object4", "ObjectB", Array(
		new PropertyDescriptor("prop2", NULL, "object3")
	), Array(
		new PropertyDescriptor(NULL, NULL, "object1")
	))
);
$factory->addObjectDescriptor(
	new ObjectDescriptor("object6", "ObjectA", Array(
		new PropertyDescriptor("prop1", NULL, "object2")
	), Array(), TRUE)
);

$factory->addObjectDescriptor(
	new ObjectDescriptor("object7", "ObjectD")
);

$obj1 = $factory->getObjectById("object1");
$obj2 = $factory->getObjectById("object2");
$obj3 = $factory->getObjectById("object3");
$obj4 = $factory->getObjectById("object4");
assert($obj1!=NULL);
assert($obj1 instanceof ObjectA);
assert($obj2!=NULL);
assert($obj2 instanceof ObjectA);
assert($obj3!=NULL);
assert($obj3 instanceof ObjectA);
assert($obj4!=NULL);
assert($obj4 instanceof ObjectB);
assert($obj1!=$obj2);
assert($obj2!=$obj3);
assert($obj3!=$obj4);

$obj = $factory->getObject(function($obj)use($obj3){
	return $obj==$obj3;
});

$obj = $factory->getObjectOfType("ObjectB");
assert($obj!=NULL); assert($obj instanceof ObjectB);
assert($obj===$obj4);

$factory2 = new ObjectFactory($factory);
$factory2->addObjectDescriptor(
	new ObjectDescriptor("object5", "ObjectC")
);

$obj5 = $factory2->getObjectById("object5");
assert($obj5!=NULL); assert($obj5 instanceof ObjectC);

$obj = $factory2->getObjectById("object1");
assert($obj!=NULL);
assert($obj instanceof ObjectA);
assert($obj==$obj1);

try {
	$obj = $factory->getObjectById("object5");
	assert(false);
} catch(Exception $ex) {
	assert(true);
}

$obj6 = $factory2->getObjectById("object6");
assert($obj6!=NULL); assert($obj6 instanceof ObjectA);

$obj7 = $factory->getObjectById("object7");
assert($obj7!=NULL);
assert($obj7 instanceof ObjectD);
assert($obj7->initialized);


?>